/*

facebookdom.js

Copyright (C) 2012 Fraunhofer Institute for Secure Information Technology

Authors: Oliver Hoffmann <oliver.hoffmann@sit.fraunhofer.de>
         Sebastian Ruhleder <sebastian.ruhleder@sit.fraunhofer.de>
		 
Contact: Andreas Poller <andreas.poller@sit.fraunhofer.de>
         Fraunhofer Institute for Secure Information Technology
		 Rheinstraße 75
		 64295 Darmstadt
		 Germany

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/gpl-3.0.txt>.

*/

/* Initialized flag. */
var isInitialized = false;

/* Interaction data handler. */
var getInteractionData = null;

/* Initialize ROSE. */
if (isInitialized) {
	log("Already initialized.");
} else {
	if (isOnFacebook()) {
		// Initialize storage.
		initStorage();

		// Start heartbeat.
		setInterval(setHeartbeat, window.HEARTBEAT_DELAY);

		// Load lanuage.
		loadLanguage();

		// Set initialized flag.
		isInitialized = true;

		openFacebookInteraction();
	} else {
		log("Not on Facebook.");
	}
}

function isCookieExpired() {
	return (document.cookie.indexOf("reminder") < 0);
}

function pulse() {

	kango.invokeAsync("kango.storage.getItem", "rose-settings", function(settings) {
		if (settings.reminder) {

			if (isCookieExpired() && !($(".reminder-flag").is(":visible"))) {
				$(".reminder-flag").fadeIn(1000);
				setTimeout(function() {
					$(".reminder-flag").fadeOut(1000);
					createCookie("reminder", true, 1);
				}, 10000);
			}

		}
	});
}

/* Mutation Observer. */
/*
 * Integrate only, when on facebook.
 */
if (isOnFacebook()) {
	// Get mutation observer.
	MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

	// config for the async kango request to get the jquery ui css file
	var details = {
		url: 'jquery-ui.css',
		method: 'GET',
		async: true,
		contentType: 'text'
	};

	// Send kange request and add css style to current page header.
	kango.xhr.send(details, function(data) {
		// Get data response.
		var content = data.response;

		// Add css to current page header.
		addStyle(content);
	});

	// create new form and hide it until it is needed
	var dialogForm = $(document.createElement('div')).attr({
		id: 'dialog-form'
	}).html('<p>' + resStr(ids_CommentBoxHeadline) + '</p><form> <fieldset style="border: none;"> <textarea style="background-color: white; width=320px" id="comment-textfield" class="text ui-widget-content ui-corner-all"></textarea> </fieldset> </form>').hide();
	// append created form to html body
	$('body').append(dialogForm);

	$("#comment-textfield").attr("placeholder", resStr(ids_CommentBoxPlaceholder));

	// configure the form to act as an dialog if someone clicks on the roses
	$("#dialog-form").dialog({
		title: resStr(ids_CommentBoxTitle),
		autoOpen: false,
		height: 400,
		width: 500,
		modal: true,
		resizable: false,
		draggable: false,
		buttons: [{
			text: resStr(ids_CommentBoxCommentButton),
			click: function() {
				var token = $(this).dialog('option', 'tok');
				var comment = $(this).find('textarea').val();
				var obj = {};
				obj['comment'] = comment;
				obj['date'] = new Date();
				setCommentByToken(token, obj);

				$(this).dialog("close");
			}
		}, {
			text: resStr(ids_CommentBoxCancelButton),
			click: function() {
				$(this).dialog("close");
			}
		}],
		open: function() {
			var cssClass = {
				'background-color': '#F6A828',
				'border': '1px solid #E78F08',
				'color': 'white'
			};
			$('.ui-dialog-buttonpane').find('button:contains("Comment")').css(cssClass);
			$('.ui-dialog-buttonpane').find('button:contains("Kommentieren")').css(cssClass);
			var token = $(this).dialog('option', 'tok');
			var comment = getCommentByToken(token);
			if (comment !== undefined) {
				var text = comment["comment"];
				$(this).find('textarea').val(text);
			}
		},
		close: function(event, ui) {
			$(this).find('textarea').val("");
			return true;
		}
	});

	setInterval(pulse, 10000);

	var observer = new MutationObserver(function(mutations, observer) {
		integrate();
	});

	observer.observe(document, {
		subtree: true,
		childList: true,
		characterData: true
	});
}

/*
 * Integrates ROSE functionality into the DOM tree of Facebook.
 */

function integrate() {
	// Register standard observers.
	for (var i = 0; i < observers.length; i++) {
		registerObserver(observers[i]);
	}

	$("#leftCol").each(function() {
		if (!$(this).hasClass('rose-integrated')) {
			$(this).addClass('rose-integrated');

			var reminderFlag = $(document.createElement('div')).attr({
				id: 'reminder-flag-left'
			}).addClass("reminder-flag")
				.text(resStr(ids_RemminderFlag))
				.hide();

			var closeFlag = $(document.createElement("a"))
				.attr({
				id: "close-flag"
			})
				.html("&times")
				.on('click', function() {
				$(reminderFlag).fadeOut("fast");
				createCookie("reminder", true, 1);
			});

			$(reminderFlag).append(closeFlag);

			$(this).append(reminderFlag);

			isReminderActive(function(b) {
				if (b && isCookieExpired()) {
					reminderFlag.show();
				}
			});
		}
	});

	$("#rightColContent").each(function() {
		if ($("#reminder-li").length <= 0) {

			var li = $(document.createElement("li"))
				.attr({
				id: "reminder-li"
			});

			var reminderFlag = $(document.createElement('div')).attr({
				id: 'reminder-flag-right'
			}).addClass("reminder-flag")
				.text(resStr(ids_RemminderFlag))
				.hide();

			var closeFlag = $(document.createElement("a"))
				.attr({
				id: "close-flag"
			})
				.html("&times")
				.on('click', function() {
				$(reminderFlag).fadeOut("fast");
				createCookie("reminder", true, 1);
			});

			$(reminderFlag).append(closeFlag);

			$(li).append(reminderFlag);

			$(".fbTimelineScrubber").append(li);

			isReminderActive(function(b) {
				if (b && isCookieExpired()) {
					reminderFlag.show();
				}
			});
		}
	});

	/* 
	 * Adds controls for commenting to every story item and
	 * adds a rose image a link and mouse action handler.
	 */
	$("ul.uiStreamHomepage > li").each(

	function() {
		if (!$(this).hasClass('rose-integrated')) {
			$(this).addClass('rose-integrated');

			var menuSpan = $(document.createElement('span')).addClass('comment-controls-icon').click(function() {
				var contentClasses = {
					".UFIComment": ".UFICommentBody",
					".photoUfiContainer": ".hasCaption",
					".uiStreamStory": ".userContent",
					".storyContent": ".userContent",
					".article": ".shareSubtext",
					".timelineUnitContainer": ".userContent"
				};
				var token = likeObserver['fbid']($(this));
				var timestamp = new Date();
				$('#dialog-form').dialog('option', 'tok', token);
				$('#dialog-form').dialog('option', 'time', timestamp);
				$('#dialog-form').dialog('open');
			});

			$(this).find(".storyInnerContent").append(menuSpan);

			$(this).mouseover(

			function() {
				$(this).find(".comment-controls-icon").show();
			}).mouseout(function() {
				$(this).find(".comment-controls-icon").hide();
			});

			$(this).find('.comment-controls-icon').mouseover(

			function() {
				$(this).stop().animate({
					"opacity": "1"
				}, "slow");
			}).mouseout(

			function() {
				$(this).stop().animate({
					"opacity": "0.25"
				}, "fast");
			});

		}
	});

	$(".fbTimelineUnit").each(

	function() {
		if (!$(this).hasClass('rose-integrated')) {
			$(this).addClass('rose-integrated');

			var menuSpan = $(document.createElement('span')).addClass('comment-controls-icon-timeline').click(function() {
				var contentClasses = {
					".UFIComment": ".UFICommentBody",
					".photoUfiContainer": ".hasCaption",
					".uiStreamStory": ".userContent",
					".storyContent": ".userContent",
					".article": ".shareSubtext",
					".timelineUnitContainer": ".userContent"
				};
				var token = likeObserver['fbid']($(this));
				var timestamp = new Date();
				$('#dialog-form').dialog('option', 'tok', token);
				$('#dialog-form').dialog('option', 'time', timestamp);
				$('#dialog-form').dialog('open');
			});

			if (!onOwnersTimeline()) {
				$(menuSpan).addClass("comment-controls-icon-timeline-friend");
			}

			// FIXIT: HACK TO PREVENT ROSE ICON ON UNWANTED STORYITEMS
			// ITEMS THAT DO NOT HAVE AN FBID
			var addRose = likeObserver['fbid']($(this));
			if (addRose === null) {
				return;
			}

			$(this).find('.timelineUnitContainer').prepend(menuSpan);

			$(this).mouseover(

			function() {
				$(this).find(".comment-controls-icon-timeline").show();
			}).mouseout(function() {
				$(this).find(".comment-controls-icon-timeline").hide();
			});

			$(this).find('.comment-controls-icon-timeline').mouseover(

			function() {
				$(this).stop().animate({
					"opacity": "1"
				}, "slow");
			}).mouseout(

			function() {
				$(this).stop().animate({
					"opacity": "0.25"
				}, "fast");
			});

		}
	});

	/*
	 * ======================================================
	 * Comment status updates.
	 * ======================================================
	 */
	$("textarea.UFIAddCommentInput").each(function() {
		// Check if already integrated.
		if (!$(this).hasClass('rose-integrated')) {
			// If not, set handler class.
			$(this).addClass('rose-integrated');

			// Register handler.
			$(this).on("keydown", function(e) {
				if (e.which == 13 || e.keyCode == 13) {
					// New comment interaction found.
					// Get comment text.
					var content = $(this).val();

					// Use like observer token as identifier.
					var object_id = likeObserver['token']($(this));

					var objectOwnerClasses = {
						'.UFIComment': 'a.UFICommentActorName',
						'div[role=article]': '.actorName a',
						'.photoUfiContainer': '.fbPhotoContributorName a',
						'div[role=article] .uiStreamMessage': 'a:nth-child(2)',
						'.timelineUnitContainer': '.fwb',
						'.storyContent': '.passiveName'
					};
					var object_owner = stripTags(findRelative($(this), objectOwnerClasses))

					// Create interaction.
					var interaction = {
						'interaction_type': 'commentstatus',
						'object_type': 'comment',
						'object_owner': hash(object_owner),
						'proband_id': getUserID(),
						'object_id': hash(object_id),
						'time': new Date(),
						'osn': "facebook"
					};

					// Save interaction.
					saveInteraction(interaction);
				}
			});
		}
	});

	/*
	 * ======================================================
	 * Chat integration: textarea integration.
	 * ======================================================
	 */
	$(".fbDockChatTabFlyout textarea.uiTextareaAutogrow, #pagelet_web_messenger textarea").each(function() {
		// Check if already integrated.
		if (!$(this).hasClass('rose-integrated')) {
			// If not, set handler class.
			$(this).addClass('rose-integrated');

			// Register handler.
			$(this).on("keydown", function(e) {
				if (e.which == 13 || e.keyCode == 13) {
					// New chat interaction found.
					// Get recipient.
					var recipient = findRelative($(this), {
						"#pagelet_web_messenger": "#webMessengerHeaderName",
						".fbDockChatTabFlyout": "a.titlebarText"
					});

					// Strip tags.
					if (recipient) recipient = stripTags(recipient);

					// Create interaction.
					var interaction = {
						'interaction_type': 'chat',
						'object_type': 'message',
						'target_person': hash(recipient),
						'proband_id': getUserID(),
						'time': new Date(),
						'osn': "facebook"
					};

					// Save interaction.
					saveInteraction(interaction);
				}
			});
		}
	});

	/*
	 * ======================================================
	 * Chat integration: submit button integration.
	 * ======================================================
	 */
	$("#pagelet_web_messenger .uiButtonConfirm input, #pagelet_web_messenger div[role=dialog] button[type=submit]").each(function() {
		// Check if already integrated.
		if (!$(this).hasClass('rose-integrated')) {
			// If not, set handler class.
			$(this).addClass('rose-integrated');

			// Register handler.
			$(this).on("click", function(e) {
				// Get recipient.
				var recipient = findRelative($(this), {
					"#pagelet_web_messenger": "#webMessengerHeaderName"
				});

				// Strip tags.
				if (recipient) recipient = stripTags(recipient);

				// Create interaction.
				var interaction = {
					'interaction_type': 'chat',
					'object_type': 'message',
					'target_person': hash(recipient),
					'proband_id': getUserID(),
					'time': new Date(),
					'osn': "facebook"
				};

				// Save interaction.
				saveInteraction(interaction);
			});
		}
	});
}

/*
 * Returns a unique ID of the proband.
 */

/* Reads the user ID.
 *
 * Return value:
 * 		User ID of current user.
 */

function getUserID() {
	// Get user ID from name of user.
	var uid = $("#headNav").find(".headerTinymanName").html();

	// Return it.
	return hash(uid);
}

/* Checks whether the user is on its timeline.
 *
 * Return value:
 * 		True if owner is on its timeline, false otherwise.
 */

function onOwnersTimeline() {
	var user = $("#headNav").find(".headerTinymanName").text();
	var siteOwner = $("#fbProfileCover").find("h2").text();

	if (user == siteOwner) {
		return true;
	} else {
		return false;
	}
}

/* Checks whether user is on Facebook.
 *
 * Return value:
 * 		True if user is on Facebook, false otherwise.
 */

function isOnFacebook() {
	return (window.location + "").indexOf("facebook.com") >= 0;
}